package edu.chl.dat076.datesite.ejbs;

import edu.chl.dat076.datesite.entities.Conversation;
import edu.chl.dat076.datesite.entities.Conversation_;
import edu.chl.dat076.datesite.entities.Message;
import edu.chl.dat076.datesite.entities.SiteUser;
import edu.chl.dat076.datesite.entities.SiteUser_;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;

/**
 *
 * @author Christoffer
 */
@Stateless
public class ConversationEJB implements ConversationEJBLocal {
	
    @PersistenceContext
    private EntityManager em;
	
	
    // Använd newConversation om getConversation returnerar null
	@Override
	public Conversation newConversation(SiteUser user1, SiteUser user2, Message firstMessage) {
		if ((user1 == null || user2 == null) && !conversationExists(user1, user2)) {
			return null;
		}
		
		Conversation newConversation = new Conversation(user1, user2);
		newConversation.addMessage(firstMessage);
		
		em.persist(newConversation);
		
		return newConversation;
	}
	
	// Hämtar och returnerar en konversation, om den finns, mellan två användare
	@Override
	public Conversation getConversation(SiteUser user1, SiteUser user2) {
		if (conversationExists(user1, user2)) {
			CriteriaBuilder builder = em.getCriteriaBuilder();
			CriteriaQuery<Conversation> query = builder.createQuery(Conversation.class);
			Root<Conversation> c = query.from(Conversation.class);

			c.join(Conversation_.users);
			
			// Kolla att båda finns med
			query.where(builder.and(
					builder.equal(c.get("users"), user1),
					builder.equal(c.get("users"), user2)));
			
			TypedQuery<Conversation> tq = em.createQuery(query);
			
			if (tq.getResultList().isEmpty()) {
				return null;
			} else {
				return tq.getResultList().get(0);
			}
		} else {
			return null;
		}
	}
	
	// Hämta alla konversationer som en användare har
	@Override
	public List<Conversation> getAllConversations(SiteUser user) {
		if (user != null) {
			CriteriaBuilder builder = em.getCriteriaBuilder();
			CriteriaQuery<Conversation> query = builder.createQuery(Conversation.class);
			Root<Conversation> c = query.from(Conversation.class);

			Join<Conversation, SiteUser> conversationUsersJoin = c.join(Conversation_.users);

			query.where(builder.equal(conversationUsersJoin.get(SiteUser_.id), user.getId()));
			
			TypedQuery<Conversation> tq = em.createQuery(query);
			
			return tq.getResultList();

		} else {
			return null;
		}
	}
	
	// Uppdatera meddelande (sätt att det är läst)
	@Override
	public Message updateMessage(Message message) {
		return em.merge(message);
	}
	
	// Lägg till meddelande till en konversation
	@Override
	public void addMessage(Conversation conversation, Message message) {
		conversation.addMessage(message);
		em.merge(conversation);
	}
	
	// Privat för att kolla om en konversation finns
	private boolean conversationExists(SiteUser user1, SiteUser user2) {
		if (user1 == null || user2 == null) {
			return false;
		}
		CriteriaBuilder builder = em.getCriteriaBuilder();
		CriteriaQuery<Conversation> query = builder.createQuery(Conversation.class);
		Root<Conversation> c = query.from(Conversation.class);
		
		Join<Conversation, SiteUser> conversationMessages = c.join(Conversation_.users);

		query.select(c).where(builder.and(
				builder.equal(c.get("users"), user1),
				builder.equal(c.get("users"), user2)));
		TypedQuery<Conversation> tq = em.createQuery(query);

		return !tq.getResultList().isEmpty();
	}
}